home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / olddatabaseupgrade.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  17.6 KB  |  564 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''Module used to upgrade from databases before we had our current scheme.
  5.  
  6. Strategy:
  7. * Unpickle old databases using a subclass of pickle.Unpickle that loads
  8.     fake class objects for all our DDBObjects.  The fake classes are just
  9.     empty shells with the upgrade code that existed when we added the schema
  10.     module.
  11.  
  12. * Save those objects to disk, using the initial schema of the new system.
  13.  
  14. '''
  15. from new import classobj
  16. from copy import copy
  17. from datetime import datetime
  18. import pickle
  19. import shutil
  20. import threading
  21. import types
  22. import time
  23. from schema import ObjectSchema, SchemaInt, SchemaFloat, SchemaSimpleItem
  24. from schema import SchemaObject, SchemaBool, SchemaDateTime, SchemaTimeDelta
  25. from schema import SchemaList, SchemaDict
  26. from fasttypes import LinkedList
  27. from types import NoneType
  28. import storedatabase
  29.  
  30. def defaultFeedIconURL():
  31.     import resources
  32.     return resources.url('images/feedicon.png')
  33.  
  34.  
  35. class DropItLikeItsHot(object):
  36.     __DropMeLikeItsHot = True
  37.     
  38.     def __slurp(self, *args, **kwargs):
  39.         pass
  40.  
  41.     
  42.     def __getattr__(self, attr):
  43.         if attr == '__DropMeLikeItsHot':
  44.             return self._DropItLikeItsHot__DropMeLikeItsHot
  45.         else:
  46.             print "DTV: WARNING! Attempt to call '%s' on DropItLikeItsHot instance" % attr
  47.             import traceback
  48.             traceback.print_stack()
  49.             return self._DropItLikeItsHot__slurp
  50.  
  51.     __setstate__ = __slurp
  52.     
  53.     def __repr__(self):
  54.         return 'DropMeLikeItsHot'
  55.  
  56.     
  57.     def __str__(self):
  58.         return 'DropMeLikeItsHot'
  59.  
  60.  
  61.  
  62. class OldDDBObject(object):
  63.     pass
  64.  
  65.  
  66. class OldItem(OldDDBObject):
  67.     allOldItems = set()
  68.     
  69.     def __setstate__(self, state):
  70.         (version, data) = state
  71.         if version == 0:
  72.             data['pendingManualDL'] = False
  73.             if not data.has_key('linkNumber'):
  74.                 data['linkNumber'] = 0
  75.             
  76.             version += 1
  77.         
  78.         if version == 1:
  79.             data['keep'] = False
  80.             data['pendingReason'] = ''
  81.             version += 1
  82.         
  83.         if version == 2:
  84.             data['creationTime'] = datetime.now()
  85.             version += 1
  86.         
  87.         if not version == 3:
  88.             raise AssertionError
  89.         data['startingDownload'] = False
  90.         self.__dict__ = data
  91.         if not issubclass(self.feed.__class__, OldDDBObject):
  92.             
  93.             try:
  94.                 self.feed = self.feed.ufeed
  95.             except:
  96.                 self.__class__ = DropItLikeItsHot
  97.  
  98.             if self.__class__ is OldFileItem:
  99.                 self.__class__ = DropItLikeItsHot
  100.             
  101.         
  102.         self.iconCache = None
  103.         if 'downloadedTime' not in data:
  104.             self.downloadedTime = None
  105.         
  106.         OldItem.allOldItems.add(self)
  107.  
  108.  
  109.  
  110. class OldFileItem(OldItem):
  111.     pass
  112.  
  113.  
  114. class OldFeed(OldDDBObject):
  115.     
  116.     def __setstate__(self, state):
  117.         (version, data) = state
  118.         if version == 0:
  119.             version += 1
  120.         
  121.         if version == 1:
  122.             data['thumbURL'] = defaultFeedIconURL()
  123.             version += 1
  124.         
  125.         if version == 2:
  126.             data['lastViewed'] = datetime.min
  127.             data['unwatched'] = 0
  128.             data['available'] = 0
  129.             version += 1
  130.         
  131.         if not version == 3:
  132.             raise AssertionError
  133.         data['updating'] = False
  134.         if not data.has_key('initiallyAutoDownloadable'):
  135.             data['initiallyAutoDownloadable'] = True
  136.         
  137.         self.__dict__ = data
  138.         if not data.has_key('actualFeed'):
  139.             self.__class__ = DropItLikeItsHot
  140.         
  141.         self.iconCache = None
  142.  
  143.  
  144.  
  145. class OldFolder(OldDDBObject):
  146.     pass
  147.  
  148.  
  149. class OldHTTPAuthPassword(OldDDBObject):
  150.     pass
  151.  
  152.  
  153. class OldFeedImpl:
  154.     
  155.     def __setstate__(self, data):
  156.         self.__dict__ = data
  157.         if 'expireTime' not in data:
  158.             self.expireTime = None
  159.         
  160.         
  161.         try:
  162.             self.updateFreq = int(self.updateFreq)
  163.         except ValueError:
  164.             self.updateFreq = -1
  165.  
  166.  
  167.  
  168.  
  169. class OldScraperFeedImpl(OldFeedImpl):
  170.     
  171.     def __setstate__(self, state):
  172.         (version, data) = state
  173.         if not version == 0:
  174.             raise AssertionError
  175.         data['updating'] = False
  176.         data['tempHistory'] = { }
  177.         OldFeedImpl.__setstate__(self, data)
  178.  
  179.  
  180.  
  181. class OldRSSFeedImpl(OldFeedImpl):
  182.     
  183.     def __setstate__(self, state):
  184.         (version, data) = state
  185.         if not version == 0:
  186.             raise AssertionError
  187.         data['updating'] = False
  188.         OldFeedImpl.__setstate__(self, data)
  189.  
  190.  
  191.  
  192. class OldSearchFeedImpl(OldRSSFeedImpl):
  193.     pass
  194.  
  195.  
  196. class OldSearchDownloadsFeedImpl(OldFeedImpl):
  197.     pass
  198.  
  199.  
  200. class OldDirectoryFeedImpl(OldFeedImpl):
  201.     
  202.     def __setstate__(self, state):
  203.         (version, data) = state
  204.         if not version == 0:
  205.             raise AssertionError
  206.         data['updating'] = False
  207.         if not data.has_key('initialUpdate'):
  208.             data['initialUpdate'] = False
  209.         
  210.         OldFeedImpl.__setstate__(self, data)
  211.  
  212.  
  213.  
  214. class OldRemoteDownloader(OldDDBObject):
  215.     
  216.     def __setstate__(self, state):
  217.         (version, data) = state
  218.         self.__dict__ = copy(data)
  219.         self.status = { }
  220.         for key in ('startTime', 'endTime', 'filename', 'state', 'currentSize', 'totalSize', 'reasonFailed'):
  221.             self.status[key] = self.__dict__[key]
  222.             del self.__dict__[key]
  223.         
  224.         self.dlid = 'noid'
  225.  
  226.  
  227.  
  228. class OldChannelGuide(OldDDBObject):
  229.     
  230.     def __setstate__(self, state):
  231.         (version, data) = state
  232.         if version == 0:
  233.             self.sawIntro = data['viewed']
  234.             self.cachedGuideBody = None
  235.             self.loadedThisSession = False
  236.             self.cond = threading.Condition()
  237.         elif not version == 1:
  238.             raise AssertionError
  239.         self.__dict__ = data
  240.         self.cond = threading.Condition()
  241.         self.loadedThisSession = False
  242.         if not data.has_key('id'):
  243.             self.__class__ = DropItLikeItsHot
  244.         
  245.  
  246.  
  247.  
  248. class OldMetainfo(OldDDBObject):
  249.     pass
  250.  
  251. fakeClasses = {
  252.     'item.Item': OldItem,
  253.     'item.FileItem': OldFileItem,
  254.     'feed.Feed': OldFeed,
  255.     'feed.FeedImpl': OldFeedImpl,
  256.     'feed.RSSFeedImpl': OldRSSFeedImpl,
  257.     'feed.ScraperFeedImpl': OldScraperFeedImpl,
  258.     'feed.SearchFeedImpl': OldSearchFeedImpl,
  259.     'feed.DirectoryFeedImpl': OldDirectoryFeedImpl,
  260.     'feed.SearchDownloadsFeedImpl': OldSearchDownloadsFeedImpl,
  261.     'downloader.HTTPAuthPassword': OldHTTPAuthPassword,
  262.     'downloader.RemoteDownloader': OldRemoteDownloader,
  263.     'guide.ChannelGuide': OldChannelGuide,
  264.     'BitTorrent.ConvertedMetainfo.ConvertedMetainfo': DropItLikeItsHot,
  265.     'downloader.DownloaderFactory': DropItLikeItsHot,
  266.     'app.StaticTab': DropItLikeItsHot,
  267.     'feed.YahooSearchFeedImpl': DropItLikeItsHot,
  268.     'downloader.BTDownloader': DropItLikeItsHot,
  269.     'downloader.BTDisplay': DropItLikeItsHot,
  270.     'downloader.HTTPDownloader': DropItLikeItsHot,
  271.     'scheduler.ScheduleEvent': DropItLikeItsHot,
  272.     'feed.UniversalFeed': DropItLikeItsHot,
  273.     'feed.RSSFeed': DropItLikeItsHot,
  274.     'feed.ScraperFeed': DropItLikeItsHot,
  275.     'feed.SearchFeed': DropItLikeItsHot,
  276.     'feed.DirectoryFeed': DropItLikeItsHot,
  277.     'feed.SearchDownloadsFeed': DropItLikeItsHot }
  278.  
  279. class FakeClassUnpickler(pickle.Unpickler):
  280.     unpickleNormallyWhitelist = [
  281.         'datetime.datetime',
  282.         'datetime.timedelta',
  283.         'time.struct_time',
  284.         'feedparser.FeedParserDict',
  285.         '__builtin__.unicode']
  286.     
  287.     def find_class(self, module, name):
  288.         fullyQualifiedName = '%s.%s' % (module, name)
  289.         if fullyQualifiedName in fakeClasses:
  290.             return fakeClasses[fullyQualifiedName]
  291.         elif fullyQualifiedName in self.unpickleNormallyWhitelist:
  292.             return pickle.Unpickler.find_class(self, module, name)
  293.         else:
  294.             raise ValueError('Unrecognized class: %s' % fullyQualifiedName)
  295.  
  296.  
  297.  
  298. class IconCache:
  299.     pass
  300.  
  301.  
  302. class DDBObjectSchema(ObjectSchema):
  303.     klass = OldDDBObject
  304.     classString = 'ddb-object'
  305.     fields = [
  306.         ('id', SchemaInt())]
  307.  
  308.  
  309. class SchemaString(SchemaSimpleItem):
  310.     
  311.     def validate(self, data):
  312.         super(SchemaSimpleItem, self).validate(data)
  313.         self.validateTypes(data, (unicode, str))
  314.  
  315.  
  316.  
  317. class SchemaSimpleContainer(SchemaSimpleItem):
  318.     '''Allows nested dicts, lists and tuples, however the only thing they can
  319.     store are simple objects.  This currently includes bools, ints, longs,
  320.     floats, strings, unicode, None, datetime and struct_time objects.
  321.     '''
  322.     
  323.     def validate(self, data):
  324.         super(SchemaSimpleContainer, self).validate(data)
  325.         self.validateTypes(data, (dict, list, tuple))
  326.         self.memory = set()
  327.         toValidate = LinkedList()
  328.         while data:
  329.             if id(data) in self.memory:
  330.                 return None
  331.             else:
  332.                 self.memory.add(id(data))
  333.             if isinstance(data, list) or isinstance(data, tuple):
  334.                 for item in data:
  335.                     toValidate.append(item)
  336.                 
  337.             elif isinstance(data, dict):
  338.                 for key, value in data.items():
  339.                     self.validateTypes(key, [
  340.                         bool,
  341.                         int,
  342.                         long,
  343.                         float,
  344.                         unicode,
  345.                         str,
  346.                         NoneType,
  347.                         datetime,
  348.                         time.struct_time])
  349.                     toValidate.append(value)
  350.                 
  351.             else:
  352.                 self.validateTypes(data, [
  353.                     bool,
  354.                     int,
  355.                     long,
  356.                     float,
  357.                     unicode,
  358.                     str,
  359.                     NoneType,
  360.                     datetime,
  361.                     time.struct_time])
  362.             
  363.             try:
  364.                 data = toValidate.pop()
  365.             continue
  366.             data = None
  367.             continue
  368.  
  369.  
  370.  
  371.  
  372. class ItemSchema(DDBObjectSchema):
  373.     klass = OldItem
  374.     classString = 'item'
  375.     fields = DDBObjectSchema.fields + [
  376.         ('feed', SchemaObject(OldFeed)),
  377.         ('seen', SchemaBool()),
  378.         ('downloaders', SchemaList(SchemaObject(OldRemoteDownloader))),
  379.         ('autoDownloaded', SchemaBool()),
  380.         ('startingDownload', SchemaBool()),
  381.         ('lastDownloadFailed', SchemaBool()),
  382.         ('pendingManualDL', SchemaBool()),
  383.         ('pendingReason', SchemaString()),
  384.         ('entry', SchemaSimpleContainer()),
  385.         ('expired', SchemaBool()),
  386.         ('keep', SchemaBool()),
  387.         ('creationTime', SchemaDateTime()),
  388.         ('linkNumber', SchemaInt(noneOk = True)),
  389.         ('iconCache', SchemaObject(IconCache, noneOk = True)),
  390.         ('downloadedTime', SchemaDateTime(noneOk = True))]
  391.  
  392.  
  393. class FileItemSchema(ItemSchema):
  394.     klass = OldFileItem
  395.     classString = 'file-item'
  396.     fields = ItemSchema.fields + [
  397.         ('filename', SchemaString())]
  398.  
  399.  
  400. class FeedSchema(DDBObjectSchema):
  401.     klass = OldFeed
  402.     classString = 'feed'
  403.     fields = DDBObjectSchema.fields + [
  404.         ('origURL', SchemaString()),
  405.         ('errorState', SchemaBool()),
  406.         ('initiallyAutoDownloadable', SchemaBool()),
  407.         ('loading', SchemaBool()),
  408.         ('actualFeed', SchemaObject(OldFeedImpl)),
  409.         ('iconCache', SchemaObject(IconCache, noneOk = True))]
  410.  
  411.  
  412. class FeedImplSchema(ObjectSchema):
  413.     klass = OldFeedImpl
  414.     classString = 'field-impl'
  415.     fields = [
  416.         ('available', SchemaInt()),
  417.         ('unwatched', SchemaInt()),
  418.         ('url', SchemaString()),
  419.         ('ufeed', SchemaObject(OldFeed)),
  420.         ('items', SchemaList(SchemaObject(OldItem))),
  421.         ('title', SchemaString()),
  422.         ('created', SchemaDateTime()),
  423.         ('autoDownloadable', SchemaBool()),
  424.         ('startfrom', SchemaDateTime()),
  425.         ('getEverything', SchemaBool()),
  426.         ('maxNew', SchemaInt()),
  427.         ('fallBehind', SchemaInt()),
  428.         ('expire', SchemaString()),
  429.         ('visible', SchemaBool()),
  430.         ('updating', SchemaBool()),
  431.         ('lastViewed', SchemaDateTime()),
  432.         ('thumbURL', SchemaString()),
  433.         ('updateFreq', SchemaInt()),
  434.         ('expireTime', SchemaTimeDelta(noneOk = True))]
  435.  
  436.  
  437. class RSSFeedImplSchema(FeedImplSchema):
  438.     klass = OldRSSFeedImpl
  439.     classString = 'rss-feed-impl'
  440.     fields = FeedImplSchema.fields + [
  441.         ('initialHTML', SchemaString(noneOk = True)),
  442.         ('etag', SchemaString(noneOk = True)),
  443.         ('modified', SchemaString(noneOk = True))]
  444.  
  445.  
  446. class ScraperFeedImplSchema(FeedImplSchema):
  447.     klass = OldScraperFeedImpl
  448.     classString = 'scraper-feed-impl'
  449.     fields = FeedImplSchema.fields + [
  450.         ('initialHTML', SchemaString(noneOk = True)),
  451.         ('initialCharset', SchemaString(noneOk = True)),
  452.         ('linkHistory', SchemaSimpleContainer())]
  453.  
  454.  
  455. class SearchFeedImplSchema(FeedImplSchema):
  456.     klass = OldSearchFeedImpl
  457.     classString = 'search-feed-impl'
  458.     fields = FeedImplSchema.fields + [
  459.         ('searching', SchemaBool()),
  460.         ('lastEngine', SchemaString()),
  461.         ('lastQuery', SchemaString())]
  462.  
  463.  
  464. class DirectoryFeedImplSchema(FeedImplSchema):
  465.     klass = OldDirectoryFeedImpl
  466.     classString = 'directory-feed-impl'
  467.  
  468.  
  469. class SearchDownloadsFeedImplSchema(FeedImplSchema):
  470.     klass = OldSearchDownloadsFeedImpl
  471.     classString = 'search-downloads-feed-impl'
  472.  
  473.  
  474. class RemoteDownloaderSchema(DDBObjectSchema):
  475.     klass = OldRemoteDownloader
  476.     classString = 'remote-downloader'
  477.     fields = DDBObjectSchema.fields + [
  478.         ('url', SchemaString()),
  479.         ('itemList', SchemaList(SchemaObject(OldItem))),
  480.         ('dlid', SchemaString()),
  481.         ('contentType', SchemaString(noneOk = True)),
  482.         ('status', SchemaSimpleContainer())]
  483.  
  484.  
  485. class HTTPAuthPasswordSchema(DDBObjectSchema):
  486.     klass = OldHTTPAuthPassword
  487.     classString = 'http-auth-password'
  488.     fields = DDBObjectSchema.fields + [
  489.         ('username', SchemaString()),
  490.         ('password', SchemaString()),
  491.         ('host', SchemaString()),
  492.         ('realm', SchemaString()),
  493.         ('path', SchemaString()),
  494.         ('authScheme', SchemaString())]
  495.  
  496.  
  497. class FolderSchema(DDBObjectSchema):
  498.     klass = OldFolder
  499.     classString = 'folder'
  500.     fields = DDBObjectSchema.fields + [
  501.         ('feeds', SchemaList(SchemaInt())),
  502.         ('title', SchemaString())]
  503.  
  504.  
  505. class ChannelGuideSchema(DDBObjectSchema):
  506.     klass = OldChannelGuide
  507.     classString = 'channel-guide'
  508.     fields = DDBObjectSchema.fields + [
  509.         ('sawIntro', SchemaBool()),
  510.         ('cachedGuideBody', SchemaString(noneOk = True)),
  511.         ('loadedThisSession', SchemaBool())]
  512.  
  513. objectSchemas = [
  514.     DDBObjectSchema,
  515.     ItemSchema,
  516.     FileItemSchema,
  517.     FeedSchema,
  518.     FeedImplSchema,
  519.     RSSFeedImplSchema,
  520.     ScraperFeedImplSchema,
  521.     SearchFeedImplSchema,
  522.     DirectoryFeedImplSchema,
  523.     SearchDownloadsFeedImplSchema,
  524.     RemoteDownloaderSchema,
  525.     HTTPAuthPasswordSchema,
  526.     FolderSchema,
  527.     ChannelGuideSchema]
  528.  
  529. def convertOldDatabase(databasePath):
  530.     OldItem.allOldItems = set()
  531.     shutil.copyfile(databasePath, databasePath + '.old')
  532.     f = open(databasePath, 'rb')
  533.     p = FakeClassUnpickler(f)
  534.     data = p.load()
  535.     if type(data) == types.ListType:
  536.         objects = data
  537.     else:
  538.         (version, objects) = data
  539.     objects = [ o[0] for o in objects ]
  540.     objects = _[2]
  541.     idMissing = set()
  542.     lastId = 0
  543.     for o in objects:
  544.         if hasattr(o, 'id'):
  545.             if o.id > lastId:
  546.                 lastId = o.id
  547.             
  548.         o.id > lastId
  549.         idMissing.add(o)
  550.     
  551.     for o in idMissing:
  552.         lastId += 1
  553.         o.id = lastId
  554.     
  555.     
  556.     def dropItFilter(obj):
  557.         return not hasattr(obj, '__DropMeLikeItsHot')
  558.  
  559.     for i in OldItem.allOldItems:
  560.         i.downloaders = filter(dropItFilter, i.downloaders)
  561.     
  562.     storedatabase.saveObjectList(objects, databasePath, objectSchemas = objectSchemas, version = 6)
  563.  
  564.